/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"

extern Ipp16s _DefLumQuantTable[64];
extern Ipp16s _DefChromQuantTable[64];
extern Ipp8u  _DefLumDCHuffBits[];
extern Ipp8u  _DefLumDCHuffValues[];
extern Ipp8u  _DefChromDCHuffBits[];
extern Ipp8u  _DefChromDCHuffValues[];
extern Ipp8u  _DefLumACHuffBits[];
extern Ipp8u  _DefLumACHuffValues[];
extern Ipp8u  _DefChromACHuffBits[];
extern Ipp8u  _DefChromACHuffValues[];

/******************************************************************************
// Name:            ijCalcQuantQualityFactor
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
int ijCalcQuantQualityFactor(int nSrcQuality) 
{
    /* Safety limit on quality factor.  Convert 0 to 1 to avoid zero divide. */
    if (nSrcQuality <= 0) nSrcQuality = 1;
    if (nSrcQuality > 100) nSrcQuality = 100;

    /* The basic table is used as-is (scaling 100) for a quality of 50.
    * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
    * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
    * to make all the table entries 1 (hence, minimum quantization loss).
    * Qualities 1..50 are converted to scaling percentage 5000/Q.
    */
    if (nSrcQuality < 50){
        nSrcQuality = 5000 / nSrcQuality;
    }
    else{
        nSrcQuality = 200 - nSrcQuality*2;
    }

    /* adjust the factor to power 2 */
    return nSrcQuality*128/100;
}


/******************************************************************************
// Name:            ijBuildEnQuantTable
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
// Output Arguments:
//                          
// Returns:          
//                  
******************************************************************************/
IJXRESULT ijBuildEnQuantTable( int  nQualityFactor,
                              BOOL bHighPrecision,
                              Ipp16s *pQTableSpec,
                              Ipp16u *pQTable )
{
    int i;
    int nValue=0;
    int nMaxValue=bHighPrecision?4095:255;
        
    for (i = 0; i < 64; i+=4) {
        nValue = (int)(*pQTableSpec++);
        nValue = (int)((nValue * nQualityFactor + 64L)>>7);
        /* limit the values to the valid range */
        if (nValue <= 0L) nValue = (int)1;
        if (nValue >nMaxValue ) nValue = nMaxValue; /* max quantizer needed for 12 bits */
        *pQTable++ = (short) (nValue);

        nValue = (int)(*pQTableSpec++);
        nValue = (int)((nValue * nQualityFactor + 64L)>>7);
        /* limit the values to the valid range */
        if (nValue <= 0L) nValue = (int)1;
        if (nValue >nMaxValue ) nValue = nMaxValue; /* max quantizer needed for 12 bits */
        *pQTable++ = (short) (nValue);

        nValue = (int)(*pQTableSpec++);
        nValue = (int)((nValue * nQualityFactor + 64L)>>7);
        /* limit the values to the valid range */
        if (nValue <= 0L) nValue = (int)1;
        if (nValue >nMaxValue ) nValue = nMaxValue; /* max quantizer needed for 12 bits */
        *pQTable++ = (short) (nValue);

        nValue = (int)*pQTableSpec++;
        nValue = (int)((nValue * nQualityFactor + 64L)>>7);
        /* limit the values to the valid range */
        if (nValue <= 0L) nValue = (int)1;
        if (nValue >nMaxValue ) nValue = nMaxValue; /* max quantizer needed for 12 bits */
        *pQTable++ = (short) (nValue);

    }

    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijBuildDecodeQuantTables
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildDecodeQuantTables(int                nNumComp,
                                   IJENCODESTATE      *pEncodeState)
{
    ippiDCTQuantInvTableInit_JPEG_16u32s(&(pEncodeState->quantTable[0]), 
                                         &(pEncodeState->dctDequantTable[0]));
    if (1<nNumComp) {
        ippiDCTQuantInvTableInit_JPEG_16u32s(&(pEncodeState->quantTable[64]), 
                                             &(pEncodeState->dctDequantTable[64]));
    }
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijBuildEncodeQuantTables
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildEncodeQuantTables(int                nNumComp,
                                   Ipp16s             *pQuantSpec,
                                   IJBITTREAMSTATE    *pStream,
                                   IJENCODESTATE      *pEncodeState)
{
    Ipp16s *pQuantTableSpec;
    IJXRESULT rtCode;

    /* Quantization table for Luminance */
    pQuantTableSpec=(NULL==pQuantSpec)?_DefLumQuantTable:pQuantSpec;

    ijBuildEnQuantTable( pEncodeState->nQuality,
                         FALSE,
                         pQuantTableSpec,
                         &(pEncodeState->quantTable[0]) );
    ippiDCTQuantFwdTableInit_JPEG_16u(&(pEncodeState->quantTable[0]), 
                                      &(pEncodeState->dctQuantTable[0]));

    rtCode=ijWrite_DQT(0, 
                       pEncodeState->nPrecision, 
                       &(pEncodeState->quantTable[0]),
                       pStream);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    /* Quantization table for Chrominance */
    if (1<nNumComp) {
        pQuantTableSpec=(NULL==pQuantSpec)?_DefChromQuantTable:&pQuantSpec[64];

        ijBuildEnQuantTable( pEncodeState->nQuality,
                             FALSE,
                             pQuantTableSpec,
                             &(pEncodeState->quantTable[64]) );

        ippiDCTQuantFwdTableInit_JPEG_16u(&(pEncodeState->quantTable[64]), 
                                      &(pEncodeState->dctQuantTable[64]));

        rtCode=ijWrite_DQT(1, 
                           pEncodeState->nPrecision, 
                           &(pEncodeState->quantTable[64]),
                           pStream);
        if (!IJX_SUCCEEDED(rtCode)){
            return rtCode;
        }
    }

    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijBuildEncodeHuffTable
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildEncodeHuffTable(int                nIdent,
                                 int                nHuffType,
                                 IJHUFFMANTABLESPEC *pHuffSpec,
                                 IJBITTREAMSTATE    *pStream,
                                 IJENCODESTATE      *pEncodeState)
{
    Ipp8u *pBits;
    Ipp8u *pValue;
    IJXRESULT rtCode;


    IppJPEGEnHuffTable *pHuffTable;

    if (0>nIdent) nIdent=0;
    else if (1<nIdent) nIdent=1;

    if (0==nHuffType) {
        pHuffTable=pEncodeState->dcHuffTable;
        if (NULL==pHuffSpec) {
            if (0==nIdent) {
                pBits=_DefLumDCHuffBits;
                pValue=_DefLumDCHuffValues;
            } else {
                pBits=_DefChromDCHuffBits;
                pValue=_DefChromDCHuffValues;
            }
        } else {
            pBits=pHuffSpec->huffBits;
            pValue=pHuffSpec->huffValue;
        }
    } else {
        nHuffType=1;
        pHuffTable=pEncodeState->acHuffTable;
        if (NULL==pHuffSpec) {
            if (0==nIdent) {
                pBits=_DefLumACHuffBits;
                pValue=_DefLumACHuffValues;
            } else {
                pBits=_DefChromACHuffBits;
                pValue=_DefChromACHuffValues;
            }
        } else {
            pBits=pHuffSpec->huffBits;
            pValue=pHuffSpec->huffValue;
        }
    }


    ippiEncodeHuffmanTableInit_JPEG_8u(pBits,pValue,&pHuffTable[nIdent]);

    rtCode=ijWrite_DHT(nIdent, nHuffType, pBits,pValue,pStream);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    return IJX_RTCODE_OK;

}

#if IPPJPVER!=1
/******************************************************************************
// Name:            _CollectScanDataFreq_A
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
// Output Arguments:
//                          
// Returns:          
//                     
//                  
******************************************************************************/

///////////////////////////////////////
#ifdef _BASELINE_A
static void _CollectScanDataFreq_A(IJBUFFER *pIJXBuffer,
                                  int **ppFreq,
                                  IJENCODESTATE *pEncodeState)
{
    int i;
    int nNumComp;
    int nMCUCount;
    const Ipp16s **ppCoeffBuf;

    IJMCUSPEC *pMCUSpec;
    IJENPROCESSSPEC *pProcSpec;

//    IJX_ASSERT(NULL!=pIJXBuffer);
//    IJX_ASSERT(NULL!=pEncodeState);

    ppCoeffBuf=(const Ipp16s **)pIJXBuffer->paCoeffBufCur;
    pMCUSpec=&(pEncodeState->mcuSpec);
    pProcSpec=&(pEncodeState->procSpec);
    nMCUCount=pMCUSpec->nTotalMCUCount;

    ijZeroMemory_4BYTE(ppFreq[0], 257);
    ijZeroMemory_4BYTE(ppFreq[1], 257);
    if (1<pEncodeState->imageSpec.nNumComponent) {
        ijZeroMemory_4BYTE(ppFreq[2], 257);
        ijZeroMemory_4BYTE(ppFreq[3], 257);
    }

    for (i=0; i<nMCUCount; i++) {
        pProcSpec->funcGetHuffmanFREQ(ppCoeffBuf, 
                                  ppFreq,
                                  pEncodeState);
        pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);
    }

    nNumComp=pEncodeState->imageSpec.nNumComponent;
    for (i=0; i<nNumComp; i++) {
        pEncodeState->dcPred[i]=0;
    }
    ijResetBuffers(pIJXBuffer);
    pEncodeState->counter.nDRICounter=pEncodeState->nRstInterval;
    pEncodeState->counter.nRSTCounter=0;
}
#endif
///////////////////////////////////////

/******************************************************************************
// Name:            ijCollectScanDataFreq_P
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
static int _CollectScanDataFreq_P(IJBUFFER *pIJXBuffer,
                                  int **ppFreq,
                                  IJENCODESTATE *pEncodeState)
{
    int i , nType;
    IJENPROCESSSPEC *pProcSpec;
    IJMCUSPEC       *pMCUSpec;
    IJSCANSPEC      *pScanSpec;
    
    pScanSpec=&(pEncodeState->scanSpec);
    pMCUSpec=&(pEncodeState->mcuSpec);

    
    if (0==(pScanSpec->ss|pScanSpec->se)) {
        int nNumComps=pEncodeState->frameSpec.nNumComps;
        int nMCUCount=pEncodeState->mcuSpec.nTotalMCUCount;
        const Ipp16s **ppCoeffBuf=(const Ipp16s **)pIJXBuffer->paImgCoeffBufCur;
        pProcSpec=&(pEncodeState->procSpec);

        ijZeroMemory_4BYTE(ppFreq[0], 257);
        ijZeroMemory_4BYTE(ppFreq[1], 257);

        for (i=0; i<nMCUCount; i++) {
            pProcSpec->funcGetHuffmanDCFREQ(ppCoeffBuf, 
                                            ppFreq, 
                                            pScanSpec->ah, 
                                            pScanSpec->al, 
                                            pEncodeState);
            pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);
        }
        ijResetBuffers(pIJXBuffer);

        for (i=0; i<nNumComps; i++) {
            pEncodeState->dcPred[i]=0;
        }
        nType=0;

    } else {
        int nIndex=pScanSpec->ppCompSpec[0]->nIdentifier;
        const Ipp16s *pMCUBuf=pIJXBuffer->paImgCoeffBufCur[nIndex];
    
        ijZeroMemory_4BYTE(ppFreq[0], 257);

        if (0==pScanSpec->ah) {
            ijGetHuffmanFREQ_ACFirst (pMCUBuf, 
                                      ppFreq[0], 
                                      pScanSpec->ss, 
                                      pScanSpec->se,
                                      pScanSpec->al,
                                      pScanSpec->ppCompSpec[0],
                                      pEncodeState);

        } else {
            
            ijGetHuffmanFREQ_ACRefine(pMCUBuf, 
                                      ppFreq[0], 
                                      pScanSpec->ss, 
                                      pScanSpec->se,
                                      pScanSpec->al,
                                      pScanSpec->ppCompSpec[0],
                                      pEncodeState);
            
        }
        nType=1;
    }

    pEncodeState->counter.nDRICounter=pEncodeState->nRstInterval;
    pEncodeState->counter.nRSTCounter=0;

    return nType;
}
#endif

/******************************************************************************
// Name:            ijBuildScanHuffTables_BLS
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
// Output Arguments:
//                          
// Returns:          
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildScanHuffTables_BLS(IJBITTREAMSTATE *pStream,
                                    IJENCODESTATE *pEncodeState)
{
    IJXRESULT rtCode;
    // DC Luminance
    rtCode=ijBuildEncodeHuffTable(0, 0, NULL, pStream, pEncodeState);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    // AC Luminance
    rtCode=ijBuildEncodeHuffTable(0, 1, NULL, pStream, pEncodeState);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    pEncodeState->paIdxDCHuffTable[0]=&(pEncodeState->dcHuffTable[0]);
    pEncodeState->paIdxACHuffTable[0]=&(pEncodeState->acHuffTable[0]);

    if (1<pEncodeState->imageSpec.nNumComponent) {
        // DC Chrominance
        rtCode=ijBuildEncodeHuffTable(1, 0, NULL, pStream, pEncodeState);
        if (!IJX_SUCCEEDED(rtCode)){
            return rtCode;
        }
        // AC Chrominance
        rtCode=ijBuildEncodeHuffTable(1, 1, NULL, pStream, pEncodeState);
        if (!IJX_SUCCEEDED(rtCode)){
            return rtCode;
        }
        pEncodeState->paIdxDCHuffTable[1]=&(pEncodeState->dcHuffTable[1]);
        pEncodeState->paIdxDCHuffTable[2]=&(pEncodeState->dcHuffTable[1]);
        pEncodeState->paIdxACHuffTable[1]=&(pEncodeState->acHuffTable[1]);
        pEncodeState->paIdxACHuffTable[2]=&(pEncodeState->acHuffTable[1]);
    }
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijBuildScanHuffTables_ABLS
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/

///////////////////////////////////////
#ifdef _BASELINE_A

IJXRESULT ijBuildScanHuffTables_ABLS(int **ppFreq,
                                     IJBUFFER *pIJXBuffer,
                                     IJBITTREAMSTATE *pStream,
                                     IJENCODESTATE *pEncodeState)
{
    IJHUFFMANTABLESPEC huffSpec;
    IJXRESULT rtCode;

    _CollectScanDataFreq_A(pIJXBuffer, ppFreq, pEncodeState);

    // DC Luminance;
    ijZeroMemory_1BYTE(huffSpec.huffBits, 16);
    ijZeroMemory_1BYTE(huffSpec.huffValue, 256);
    ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[0],
                                  huffSpec.CODESIZE,
                                  huffSpec.OTHERS,
                                  huffSpec.BITS,
                                  huffSpec.huffBits,
                                  huffSpec.huffValue);
    rtCode=ijBuildEncodeHuffTable(0, 0, &huffSpec,  
                                  pStream, pEncodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    }
    // AC Luminance;
    ijZeroMemory_1BYTE(huffSpec.huffBits, 16);
    ijZeroMemory_1BYTE(huffSpec.huffValue, 256);
    ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[1],
                                  huffSpec.CODESIZE,
                                  huffSpec.OTHERS,
                                  huffSpec.BITS,
                                  huffSpec.huffBits,
                                  huffSpec.huffValue);
    rtCode=ijBuildEncodeHuffTable(0, 1, &huffSpec,  
                                  pStream, pEncodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    }

    pEncodeState->paIdxDCHuffTable[0]=&(pEncodeState->dcHuffTable[0]);
    pEncodeState->paIdxACHuffTable[0]=&(pEncodeState->acHuffTable[0]);

    if (1<pEncodeState->imageSpec.nNumComponent) {
        // DC Chrominance;
        ijZeroMemory_1BYTE(huffSpec.huffBits, 16);
        ijZeroMemory_1BYTE(huffSpec.huffValue, 256);
        ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[2],
                                      huffSpec.CODESIZE,
                                      huffSpec.OTHERS,
                                      huffSpec.BITS,
                                      huffSpec.huffBits,
                                      huffSpec.huffValue);
        rtCode=ijBuildEncodeHuffTable(1, 0, &huffSpec,  
                                      pStream, pEncodeState);
        if (!IJX_SUCCEEDED(rtCode)) {
            return rtCode;
        }
        // AC Chrominance;
        ijZeroMemory_1BYTE(huffSpec.huffBits, 16);
        ijZeroMemory_1BYTE(huffSpec.huffValue, 256);
        ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[3],
                                      huffSpec.CODESIZE,
                                      huffSpec.OTHERS,
                                      huffSpec.BITS,
                                      huffSpec.huffBits,
                                      huffSpec.huffValue);
        rtCode=ijBuildEncodeHuffTable(1, 1, &huffSpec,  
                                      pStream, pEncodeState);
        if (!IJX_SUCCEEDED(rtCode)) {
            return rtCode;
        }
        pEncodeState->paIdxDCHuffTable[1]=&(pEncodeState->dcHuffTable[1]);
        pEncodeState->paIdxDCHuffTable[2]=&(pEncodeState->dcHuffTable[1]);
        pEncodeState->paIdxACHuffTable[1]=&(pEncodeState->acHuffTable[1]);
        pEncodeState->paIdxACHuffTable[2]=&(pEncodeState->acHuffTable[1]);
    } 
    return IJX_RTCODE_OK;
}

#endif
///////////////////////////////////////

#if IPPJPVER!=1
/******************************************************************************
// Name:            ijBuildScanHuffTables_P
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildScanHuffTables_P(int **ppFreq,
                                  IJBITTREAMSTATE *pStream,
                                  IJENCODESTATE *pEncodeState)
{
    int nIdent, nType;
    IJHUFFMANTABLESPEC huffSpec;
    int nNumComps=pEncodeState->scanSpec.nNumComps;
    IJCOMPSPEC **ppCompSpec=pEncodeState->scanSpec.ppCompSpec;
    IJBUFFER *pIJXBuffer=&(pEncodeState->bufSpec);
    IJXRESULT rtCode;
    
    nType=_CollectScanDataFreq_P(pIJXBuffer, ppFreq, pEncodeState);
    
    ijZeroMemory_1BYTE(&huffSpec, sizeof(IJHUFFMANTABLESPEC));

    ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[0],
                                  huffSpec.CODESIZE,
                                  huffSpec.OTHERS,
                                  huffSpec.BITS,
                                  huffSpec.huffBits,
                                  huffSpec.huffValue);

    nIdent=(0==nType)?
                      ppCompSpec[0]->nDCHuffTableIndex:
                      ppCompSpec[0]->nACHuffTableIndex;

    rtCode=ijBuildEncodeHuffTable(nIdent, nType, &huffSpec,  
                                  pStream, pEncodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    } 

    if (1<nNumComps) {
        ijZeroMemory_1BYTE(&huffSpec, sizeof(IJHUFFMANTABLESPEC));

        ippiHuffmanTableSpecInit_JPEG_8u(ppFreq[1],
                                      huffSpec.CODESIZE,
                                      huffSpec.OTHERS,
                                      huffSpec.BITS,
                                      huffSpec.huffBits,
                                      huffSpec.huffValue);
        nIdent=(0==nType)?
                          ppCompSpec[1]->nDCHuffTableIndex:
                          ppCompSpec[1]->nACHuffTableIndex;

        rtCode=ijBuildEncodeHuffTable(nIdent, nType,&huffSpec,  
                                      pStream, pEncodeState);
        if (!IJX_SUCCEEDED(rtCode)) {
            return rtCode;
        }

    }

    return IJX_RTCODE_OK;
}
#endif

/******************************************************************************
// Name:            ijBuildDefaultDecodeTables
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficient buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijBuildDefaultDecodeTables(IJDECODESTATE *pDecodeState)
{
    int i;
    Ipp8u quantTable[64*sizeof(Ipp16u)+31];
    Ipp16u *pQuantTable;
    pQuantTable=(Ipp16u *)IIP_ALIGN_32B(quantTable);

    /* Quantization table for Luminance */
    for (i=0; i<64; i++) {
        pQuantTable[i]=_DefLumQuantTable[i];
    }
    ippiDCTQuantInvTableInit_JPEG_16u32s( pQuantTable, 
                                          &(pDecodeState->dctDequantTable[0]));
    pDecodeState->paIdxDCTDequantTable[0]=&(pDecodeState->dctDequantTable[0]);
    pDecodeState->paIdxDCTDequantTable[3]=&(pDecodeState->dctDequantTable[0]);

    /* Quantization table for Chrominance */
    for (i=0; i<64; i++) {
        pQuantTable[i]=_DefChromQuantTable[i];
    }
    ippiDCTQuantInvTableInit_JPEG_16u32s(pQuantTable, 
                                         &(pDecodeState->dctDequantTable[64]));
    pDecodeState->paIdxDCTDequantTable[1]=&(pDecodeState->dctDequantTable[64]);
    pDecodeState->paIdxDCTDequantTable[2]=&(pDecodeState->dctDequantTable[64]);

    /* Huffman table for DC of Luminance */
    
    ippiDecodeHuffmanTableInit_JPEG_8u(_DefLumDCHuffBits,
                                     _DefLumDCHuffValues,
                                     &(pDecodeState->dcHuffTable[0]));
    pDecodeState->paIdxDCHuffTable[0] = &(pDecodeState->dcHuffTable[0]);
    pDecodeState->paIdxDCHuffTable[3] = &(pDecodeState->dcHuffTable[0]);
        
    /* Huffman table for DC of Chrominance */
    ippiDecodeHuffmanTableInit_JPEG_8u(_DefChromDCHuffBits,
                                     _DefChromDCHuffValues,
                                     &(pDecodeState->dcHuffTable[1]));
    pDecodeState->paIdxDCHuffTable[1] = &(pDecodeState->dcHuffTable[1]);
    pDecodeState->paIdxDCHuffTable[2] = &(pDecodeState->dcHuffTable[1]);

    /* Huffman table for AC of Luminance */
    ippiDecodeHuffmanTableInit_JPEG_8u(_DefLumACHuffBits,
                                     _DefLumACHuffValues,
                                     &(pDecodeState->acHuffTable[0]));
    pDecodeState->paIdxACHuffTable[0] = &(pDecodeState->acHuffTable[0]);
    pDecodeState->paIdxACHuffTable[3] = &(pDecodeState->acHuffTable[0]);

    /* Huffman table for AC of Chrominance */
    ippiDecodeHuffmanTableInit_JPEG_8u(_DefChromACHuffBits,
                                     _DefChromACHuffValues,
                                     &(pDecodeState->acHuffTable[1]));
    pDecodeState->paIdxACHuffTable[1] = &(pDecodeState->acHuffTable[1]);
    pDecodeState->paIdxACHuffTable[2] = &(pDecodeState->acHuffTable[1]);

    return IJX_RTCODE_OK;
}
/* EOF */
